import { defineStore } from 'pinia';
import { generate } from 'shortid';
import db from '../database';

export enum EventType {
    Comment = 'comment',
    Variable = 'var',
    Block = 'block',
}


export class EventComment {
    public id = generate();
    type = EventType.Comment;
    comment: string;
    
    constructor(comment: string) {
        this.comment = comment;
    }
}

export class EventVariable {
    public id = generate();
    type = EventType.Variable;
    
    constructor() {
    }
}

export class EventCondition {
    public id = generate();
    public target = ''; // 条件的目标
    public condition = '';// 目标的条件
    public param: any;
}

export class EventAction {
    public id = generate();
    public target = '';
    public action = '';
    public param = '';
}

export class EventBlock {
    id = generate();
    type = EventType.Block;
    conditions: EventCondition[] = [];
    actions: EventAction[] = [];
    
    constructor() {
    }
}

export class EventSheet {
    id = '';
    data: Array<EventComment | EventVariable | EventBlock> = [];
    
    constructor(id?: string) {
        this.id = id || generate();
    }
}


export interface IEventsState {
    sheets: EventSheet[],
}


const eventsStore = defineStore('events', {
    state: (): IEventsState => {
        return {
            sheets: [],
        };
    },
    actions: {
        toConfig() {
            return {
                key: 'events',
            };
        },
        getSheet(id: string): EventSheet | null {
            return this.sheets.find(el => el.id === id) || null;
        },
        init(data: IEventsState) {
            this.sheets = data.sheets;
        },
        removeSheet(id: string) {
            const idx = this.sheets.findIndex(el => el.id === id);
            if (idx !== -1) {
                this.sheets.splice(idx, 1);
            }
        },
        createSheet(id?: string): EventSheet {
            const item: EventSheet = new EventSheet(id);
            // const comment: EventComment = new EventComment('注释');
            // item.data.push(comment);
            //
            // const block: EventBlock = new EventBlock();
            // item.data.push(block);
            this.sheets.push(item);
            return item;
        },
        loadSheet(id: string): EventSheet | null {
            return this.sheets.find(el => el.id === id) || null;
        },
        removeSheetItem(sheetID: string, itemID: string) {
            const sheet = this.getSheet(sheetID);
            if (sheet) {
                const idx = sheet.data.findIndex(el => el.id === itemID);
                if (idx !== -1) {
                    sheet.data.splice(idx, 1);
                    db.save();
                    return true;
                }
            }
            return false;
        },
        addComment(sheetID: string) {
            const sheet = this.getSheet(sheetID);
            if (sheet) {
                sheet.data.push(new EventComment('注释'));
                db.save();
            }
        },
        removeComment(sheetID: string, commonID: string) {
            this.removeSheetItem(sheetID, commonID);
        },
        changeComment(sheetID: string, commentID: string, value: string) {
            const item = this._getSheetItem(sheetID, commentID);
            if (item) {
                (item as EventComment).comment = value;
                db.save();
            }
        },
        addBlock(sheetID: string) {
            const sheet = this.getSheet(sheetID);
            if (sheet) {
                const block = new EventBlock();
                sheet.data.push(block);
                db.save();
                return block;
            }
            return null;
        },
        addBlockCondition(sheetID: string, blockID: string, opts: {
            bundleOrObjID: string,
            condition: string,
        }) {
            const sheet = this.getSheet(sheetID);
            if (sheet) {
                const ret = sheet.data.find(el => el.id === blockID);
                if (ret) {
                    const cond = new EventCondition();
                    cond.target = opts.bundleOrObjID;
                    cond.condition = opts.condition;
                    (ret as EventBlock).conditions.push(cond);
                    db.save();
                }
            }
        },
        addBlockAction(sheetID: string, blockID: string, opts: {
            target: string,
            action: string,
        }) {
            const sheet = this.getSheet(sheetID);
            if (sheet) {
                const ret = sheet.data.find(el => el.id === blockID);
                if (ret) {
                    const action = new EventAction();
                    action.target = opts.target;
                    action.action = opts.action;
                    (ret as EventBlock).actions.push(action);
                    db.save();
                }
            }
        },
        _getSheetItem(sheetID: string, blockID: string) {
            const sheet = this.getSheet(sheetID);
            if (sheet) {
                return sheet.data.find(el => el.id === blockID) || null;
            }
            return null;
        },
        removeBlockCondition(sheetID: string, blockID: string, conditionID: string) {
            const eventBlock = this._getSheetItem(sheetID, blockID);
            if (eventBlock) {
                const conditions: EventCondition[] = (eventBlock as EventBlock).conditions;
                const idx = conditions.findIndex(el => el.id === conditionID);
                if (idx !== -1) {
                    conditions.splice(idx, 1);
                    db.save();
                }
            }
        },
        removeBlockAction(sheetID: string, blockID: string, actionID: string) {
            const eventBlock = this._getSheetItem(sheetID, blockID);
            if (eventBlock) {
                const actions: EventAction[] = (eventBlock as EventBlock).actions;
                const idx = actions.findIndex(el => el.id === actionID);
                if (idx !== -1) {
                    actions.splice(idx, 1);
                    db.save();
                }
            }
        },
        getItemIndex(sheetID: string, itemID: string) {
            const sheet = this.getSheet(sheetID);
            if (sheet) {
                const blocks = sheet.data.filter((item) => {
                    return item.type === EventType.Block;
                });
                const idx = blocks.findIndex(el=>el.id === itemID);
                if (idx !== -1) {
                    return idx + 1;
                }
            }
            return 0;
        },
    },
});
export default eventsStore;